package de.ret_world.openrpgstudio.mapeditor.scripts;

import de.ret_world.openrpgstudio.editor.Project;
import de.ret_world.openrpgstudio.editor.script.Point;
import de.ret_world.openrpgstudio.editor.script.ScriptObject;
import java.util.HashMap;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;

/**
 * A Layer of a TileMap for storing Tiles or collision information.
 *
 * @author Emu
 */
public class Layer implements ScriptObject {

    public static enum TYPE {

        TILE, EVENT
    }
    private HashMap<Point, Integer> points = new HashMap<>();
    private String ID = "";
    private int index = 0;
    private TYPE type = TYPE.TILE;
    private TileSet tileset = null;
    private TileMap parentMap = null;

    @Override
    public void create(LuaValue val) {
        if (!val.get("id").isnil()) {
            ID = val.get("id").toString();
        }
        if (!val.get("type").isnil()) {
            type = TYPE.valueOf(val.get("type").toString());
        }
        if (!val.get("tileset").isnil()) {
            tileset = (TileSet) Project.getInstance().getDatabase().getScriptObject(TileSet.TYPE, val.get("tileset").toString());
        }
        if (!val.get("map").isnil() && val.get("map").istable()) {
            LuaValue v = val.get("map");
            for (int x = 1; x <= parentMap.getWidth(); x++) {
                for (int y = 1; y <= parentMap.getHeight(); y++) {
                    int i = -1;
                    LuaValue integer = v.get(y).get(x);
                    if (integer != null && integer.isint()) {
                        i = integer.toint();
                    }
                    if (i >= 0) {
                        points.put(new Point(x - 1, y - 1), i);
                    }
                }
            }
        }
    }

    @Override
    public LuaTable toLua() {
        LuaTable lua = new LuaTable();
        lua.set("id", LuaTable.valueOf(ID));
        lua.set("type", LuaTable.valueOf(type.toString()));
        lua.set("tileset", LuaTable.valueOf(tileset.getID()));
//        for (int x = 1; x <= parentMap.getWidth(); x++) {
//            LuaTable map = new LuaTable();
//            for (int y = 1; y <= parentMap.getHeight(); y++) {
//                LuaTable xmap = new LuaTable();
//                
//            }
//        }

        return lua;
    }

    @Override
    public String toScript() {
        String s = "tilemap.layer[" + (index + 1) + "] = {} -- init new layer\n"
                + "tilemap.layer[" + (index + 1) + "].id = '" + ID + "'\n"
                + "tilemap.layer[" + (index + 1) + "].type = '" + type.toString() + "'\n";
        
        if (type.equals(TYPE.TILE)) {
            s += "tilemap.layer[" + (index + 1) + "].tileset = '" + tileset.getID() + "'\n";
        }
        
        s += "tilemap.layer[" + (index + 1) + "].map = {";
        for (int y = 0; y < parentMap.getWidth(); y++) {
            s += "\n\t{";
            for (int x = 0; x < parentMap.getHeight(); x++) {
                Integer i = points.get(new Point(x, y));
                if (i != null) {
                    s += i + ", ";
                } else {
                    s += "-1, ";
                }
            }
            s = s.substring(0, s.length() - 2);
            s += "},";

        }
        s = s.substring(0, s.length() - 1);
        s += "\n}\n";

        return s;
    }

    public String getID() {
        return ID;
    }

    public void setID(String ID) {
        this.ID = ID;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    public int getIndex() {
        return index;
    }

    public TileMap getParentMap() {
        return parentMap;
    }

    public void setParentMap(TileMap parentMap) {
        this.parentMap = parentMap;
    }

    public HashMap<Point, Integer> getPoints() {
        return points;
    }

    public TileSet getTileset() {
        return tileset;
    }

    public void setTileset(TileSet tileset) {
        this.tileset = tileset;
    }

    public TYPE getType() {
        return type;
    }

    public void setType(TYPE type) {
        this.type = type;
    }

    @Override
    public String toString() {
        return getID();
    }
}
